home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 1 / ETO Development Tools 1.iso / Essentials / MacApp Documentation / MacApp AppleLink Messages / MacApp.Tech$ Oct 89 / Z0029-Re Object Pascal Qu-Oct89 < prev    next >
Encoding:
Text File  |  1989-10-09  |  3.5 KB  |  153 lines  |  [TEXT/GEOL]

  1. Item    9116153                         8-Oct-89        09:41
  2.  
  3. From:   SCHMUCKER1                      Schmucker, Kurt
  4.  
  5. To:     D0738                           Kane Biomedical System, S Helm,PRT
  6.  
  7. cc:     MACAPP.TECH$                    MACAPP Tech
  8.         DEREK                           White, Derek
  9.         NASSI                           Nassi, Ike
  10.         APPLE.BUGS                      Apple Bugs Reporting
  11.  
  12. Sub:    Re: Object Pascal Question
  13.  
  14. Jeffrey,
  15.  
  16.     You are correct that it is not easy to do what you want (have mutual
  17. references between two Object Pascal classes) -- but it should be!  The
  18. following small program illustrates the problem:
  19.  
  20. ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
  21. PROGRAM MutualRefTest;
  22.  
  23. USES
  24.    ObjIntf;
  25.  
  26. TYPE
  27.  
  28.    TFooObject  = OBJECT (TObject)
  29.    fMyFrob:TFrobObject;
  30.    PROCEDURE TFooObject.IFooObject;
  31.    END;
  32.  
  33.    TFrobObject = OBJECT(TObject)
  34.    fMyFoo: TFooObject;
  35.    PROCEDURE TFrobObject.IFrobObject;
  36.    END;
  37.  
  38.  
  39. VAR
  40.    aFoo:   TFooObject;
  41.    aFrob:  TFrobObject;
  42.  
  43.  
  44. PROCEDURE TFooObject.IFooObject;
  45. BEGIN
  46. END;
  47.  
  48. PROCEDURE TFrobObject.IFrobObject;
  49. BEGIN
  50. END;
  51.  
  52. BEGIN
  53.    NEW(aFoo);
  54.    NEW(aFrob);
  55.  
  56.    aFrob.fMyFoo := aFoo;
  57.    aFoo.fMyFrob := aFrob;
  58. END.
  59.  
  60. ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
  61.  
  62. Compiling this  results in the following Pascal error:
  63.  
  64.    pascal MutualRefTest.p
  65. #  aFrob.fMyFoo := aFoo;
  66. #  aFoo.fMyFrob := aFrob;
  67. #                       ?
  68. ### pascal - Error 144 Type conflict of operands
  69. #-----------------------------------------------------------------------
  70.     File "MutualRefTest.p"; Line 37
  71. #-----------------------------------------------------------------------
  72.  
  73.  
  74. HOWEVER, reversing the order of the definitions of TFoo and TFrob results in
  75. the following error:
  76.  
  77. #
  78. #  aFrob.fMyFoo := aFoo;
  79. #                      ?
  80. ### pascal - Error 144 Type conflict of operands
  81. #-------------------------------------------------------------------------
  82.     File "MutualRefTest.p"; Line 35
  83. #-------------------------------------------------------------------------
  84.  
  85.  
  86.  
  87.  
  88.     I believe that this problem has been corrected in MPW Pascal 3.1 which is
  89. now in testing.  When I get my copy (in a week or so, I hope), I will re-run
  90. this test and post the result.
  91.  
  92.  
  93.     In the meantime, the solution appears to be to declare (at least) the first
  94. such mutual reference as a TObject, and then cast the value whenever you use
  95. it.  (Shown below.)  I don't think that your suggestion of using Member is the
  96. way to proceed.  Except in very rare cases (some of which can be seen in
  97. UDialog), Member is usually a mistake as a way out of a difficult problem or,
  98. in this case, a compiler glitch.
  99.  
  100.     In terms of making your job easier, it might be best to just have BOTH
  101. references defined as TObjects, and always cast every use, rather than having
  102. to always remember which of them was declared first.
  103.  
  104.  
  105. The Workaround
  106.  
  107. PROGRAM MutualRefTestFix;
  108.  
  109. USES
  110.    ObjIntf;
  111.  
  112. TYPE
  113.  
  114.    TFooObject  = OBJECT (TObject)
  115.    fMyFrob:TObject;     { ••••••••••• Note change ••••••••••• }
  116.    PROCEDURE TFooObject.IFooObject;
  117.    END;
  118.  
  119.    TFrobObject = OBJECT(TObject)
  120.    fMyFoo: TFooObject;
  121.    PROCEDURE TFrobObject.IFrobObject;
  122.    END;
  123.  
  124.  
  125. VAR
  126.    aFoo:   TFooObject;
  127.    aFrob:  TFrobObject;
  128.  
  129.  
  130. PROCEDURE TFooObject.IFooObject;
  131. BEGIN
  132. END;
  133.  
  134. PROCEDURE TFrobObject.IFrobObject;
  135. BEGIN
  136. END;
  137.  
  138. BEGIN
  139.    NEW(aFoo);
  140.    NEW(aFrob);
  141.  
  142.    aFrob.fMyFoo := aFoo;
  143.    aFoo.fMyFrob := aFrob;
  144.  
  145.    { When USING the value of fMyFrob, always cast it. }  { ••• Change •••• }
  146.    TFrobObject(aFoo.fMyFrob).IFrobObject;
  147. END.
  148.  
  149.  
  150.  
  151.             Kurt
  152.  
  153.